#include "particle.h"
#include "ground.h"

particle::particle(QPointF Pos, float r, ground* groundHandle)
    : Pos(Pos)
    , color("#79C99E")
    , groundHandle(groundHandle)
    , pressureM(2000.f)
    , vx(0.f)
    , vy(0.f)
    , r(r)
{

}

void particle::xsph_add(float fx, float fy, float dt)
{
    vx += fx * dt;
    vy += fy * dt;
}

void particle::xsph_sub(float fx, float fy, float dt)
{
    vx -= fx * dt;
    vy -= fy * dt;
}

void particle::applynewton3_add(float fx, float fy, float mass, float dt)
{
    vx +=  fx / mass * dt;
    vy +=  fy / mass * dt;
}

void particle::applynewton3_sub(float fx, float fy, float mass, float dt)
{
    vx -=  fx / mass * dt;
    vy -=  fy / mass * dt;
}

void particle::applygravity()
{
    vy += g;
}

float particle::DensitytoPressure(float density)
{
    float densityerror = density - targetdensity;
    float pressure = densityerror * pressureM;
    return pressure;
}

void particle::applyPressure(float ang, float magnitude)
{
    vx += std::sin(ang) * magnitude * 0.01f;
    vy += std::cos(ang) * magnitude * 0.01f;
}

void particle::moveStep()
{
    float dt = 0.3f;
    /* 2.1 速度 → 位置 */
    float x = Pos.x() + vx * dt;
    float y = Pos.y() + vy * dt;

    const float left = r;
    const float right  = groundHandle->size().width()  - r;
    const float top    = r;
    const float bottom = groundHandle->size().height() - r;

    /* 2.2 边界碰撞：镜像回场内 + 速度反弹 */
    if (x < left) {
        x  = left + (left - x);   vx = -vx * e;
    } else if (x > right) {
        x  = right - (x - right); vx = -vx * e;
    }
    if (y < top) {
        y  = top + (top - y);     vy = -vy * e;
    } else if (y > bottom) {
        y  = bottom - (y - bottom); vy = -vy * e;
    }

    /* 2.3 写回坐标 */
    Pos.setX(x);
    Pos.setY(y);

    /* 2.4 阻尼（可选）*/
    vx *= drag;
    vy *= drag;
}
